(function ($) {
	var me = {};
	window.FormElement = Class.create({
		// 继承的父类
		Extends: Basis,
		// 混入的集合
		//Mixes: EventMixin,
		// 静态方法
		//Statics: {},
		// 构造
		constructor: function(element, options){
			this.element = $(element);
			me = this;
			// 清空数据
			me.set('elementOption',[]);
			me.set('editData',{});
			// 清空数据
			$.each(options,function(k,v){
				if( v == undefined && v == null ) return true;
				if( typeof v === 'object' ) {
					$.extend(me.get(k),v);
				} else {
					me.set(k,v);
				}
			});
			// 设置配置
			me.set('formId',this.element.attr('id'));
		},
		// 表单ID
		formId: "",
		// 编辑页数据
		editData: {},
		// 表单元素验证规则
		validateRules: {},
		// 表单元素验证提示
		validateMessages: {},
		// 表单配置
		elementOption: [],
		// 表单元素模板
		elementTpl: '<div class="form-group">' +
				'<label class="col-sm-3 control-label no-padding-right" for="form-field-2">{2}{0}：</label>' +
				'<div class="col-sm-9">' +
					'{1}' +
				'</div>' +
			'</div>' +
			'<div class="space-4"></div>',
		// 标记模板
		markTpl: '<span class="red">*</span>',
		// 提示模板
		tipsTpl: ' data-rel="tooltip" data-placement="bottom" ',
		// 分隔模板
		separateTpl: '<span class="input-group-addon">' +
					'<i class="fa glyphicon-minus"></i>' +
				'</span>',
		// 父级模板
		parentTpl: '<div class="input-group">' +
					'{0}' +
				'</div>',
		// 后缀模板
		titleSuffixTpl:'<span>&nbsp;&nbsp;{0}&nbsp;&nbsp;</span>',
		// 前缀模板
		titlePrefixTpl:'<span>&nbsp;&nbsp;{0}&nbsp;&nbsp;</span>',
		// input模板
		inputTpl: '{13}<input type="{0}" name="{2}" class="{3} {1}" value="{4}" placeholder="{5}" {6} {7} {10} {11} data-original-title="{12}" />{14}',
		// input组装
		inputBuild: function(option){},
		// input渲染
		inputRender: function( option ){},
		// date模板
		datetimeTpl: '<input type="text" name="{2}" class="{3} {1}" value="{4}" data-placeholder="{5}" {6} {7} data-date-format="{8}" {10} {11} data-original-title="{12}" />',
		// datetime组装
		datetimeBuild: function(option){},
		// datetime渲染
		datetimeRender: function( option ){
			$('.' + option.id).datetimepicker({
				//format: 'YYYY/MM/DD HH:mm:ss',//use this option to display seconds
				icons: {
					time: 'fa fa-clock-o',
					date: 'fa fa-calendar',
					up: 'fa fa-chevron-up',
					down: 'fa fa-chevron-down',
					previous: 'fa fa-chevron-left',
					next: 'fa fa-chevron-right',
					today: 'fa fa-arrows ',
					clear: 'fa fa-trash',
					close: 'fa fa-times'
				}
			}).next().on(ace.click_event, function(){
				$(this).prev().focus();
			});
		},
		// select模板
		selectTpl: '<select name="{2}" class="{3} {1}" data-placeholder="{5}" {9} >' +
					'{4}' +
				'</select>',
		// select组装
		selectBuild: function(option){
			var list = {}, html = option.multiple ? '' : '<option value="">' + ( option.placeholder != '' ? option.placeholder : "" ) + '</option>';
			if( typeof(option.data) == "object" ) {
				$.each(option.data,function(key,val){
					if( typeof(val) == "object" ) {
						list[val[option.fieldKey]] = val[option.fieldValue];
					} else if( typeof(val) == "string" ) {
						list[key] = val;
					}
				});
			} else if( typeof(option.data) == "string" ) {
				$.ajax({
					type: "get",
					dataType: "json",
					url: me.getUrl(option.data),
					data: option.dataParam || {},
					async: false,
					success: function(data){
						var dataList = option.dataSrc != '' ? data.result : data ;
						$.each(dataList,function(key,val){
							if( typeof(val) == "object" ) {
								list[val[option.fieldKey]] = val[option.fieldValue];
							} else if( typeof(val) == "string" ) {
								list[key] = val;
							}
						});
					},
					error: function(data){}
				});
				
			}
			var value = ( me.editData[option.id] != undefined && me.editData[option.id] !== '' ) ? me.editData[option.id] : option.value;
			value = value ? value.toString().split(',') : [];
			$.each(list,function(key,val){
				var selected = '';
				if( option.op == 'wise' && ( parseInt(value[0]) & key ) == key ) {
					selected = 'selected';					
				} else if( $.inArray(key,value) !== -1 ) {
					selected = 'selected';
				}
				html += '<option ' + selected + ' value="' + key + '">' + val + '</option>';
			});
			return html;
		},
		// select渲染
		selectRender: function( option ){
			if( me.formId.indexOf("Search") != -1 ) return;
			if( ace.vars['touch']) return;
			$('.' + option.id).chosen({allow_single_deselect:true});
		},
		// text模板
		textareaTpl: '<div class="clearfix">' +
						'<textarea name="{2}" class="{3} {1}" placeholder="{5}" {6} {7} {10} {11} data-original-title="{12}" >{4}</textarea>' +
					'</div>',
		// textarea组装
		textareaBuild: function(option){},
		// textarea渲染
		textareaRender: function( option ){},
		// image参数
		imageOption: {
			rel: 'colorbox',
			reposition:true,
			scalePhotos:true,
			scrolling:false,
			previous:'<i class="ace-icon fa fa-arrow-left"></i>',
			next:'<i class="ace-icon fa fa-arrow-right"></i>',
			close:'&times;',
			current:'{current} of {total}',
			maxWidth:'100%',
			maxHeight:'100%',
			onOpen:function(){
				$overflow = document.body.style.overflow;
				document.body.style.overflow = 'hidden';
			},
			onClosed:function(){
				document.body.style.overflow = $overflow;
			},
			onComplete:function(){
				$.colorbox.resize();
			}
		},
		// image模板
		imageTpl: '<ul class="ace-thumbnails clearfix">' +
				'<li>' +
					'<a href="{4}" data-rel="colorbox">' +
						'<img width="150" height="150" alt="150x150" src="{4}" />' +
						'<div class="text">' +
							'<div class="inner">' +
							'</div>' +
						'</div>' +
					'</a>' +
					'<div class="tools tools-bottom">' +
						//'<a href="javascript:;" class="image-upload">' +
							//'<i class="ace-icon fa fa-cloud-upload"></i>' +
						//'</a>' +
						'<a href="javascript:;" class="image-pencil">' +
							'<i class="ace-icon fa fa-pencil"></i>' +
						'</a>' +
						//'<a href="javascript:;" class="image-times">' +
							//'<i class="ace-icon fa fa-times red"></i>' +
						//'</a>' +
					'</div>' +
				'</li>' +
			'</ul>' +
			'<div class="text">' +
				'<input type="text" name="{2}" class="hidden {3} {1}" value="{4}" placeholder="{5}" {6} {7} {10} {11} data-original-title="{12}" />' +
			'</div>',
		// image组装
		imageBuild: function(option){
		},
		// image渲染
		imageRender: function( option ){
			var $overflow = '';
			$('.ace-thumbnails [data-rel="colorbox"]').colorbox(me.imageOption);
			$('.image-pencil').on('click', function(){
				var $this = $(this);
				//var $input = $this.parent().parent().find("input");
				var $input = $this.parents('ul').next().find("input");
				$input.removeClass("hidden");
			});
			$('.' + option.id).on('blur', function(){
				var $this = $(this);
				var value = $this.val();
				var $imgA = $this.parent().parent().find('a[data-rel="colorbox"]');
				var $img = $imgA.find("img");
				$imgA.attr("href",getImgUrl(value));
				$img.attr("src",getImgUrl(value));
				$this.addClass("hidden");
			});
		},
		// file参数
		fileOption: {
			style : 'well',
			no_file: '',
			btn_choose: '将文件拖放到此处或单击以选择',
			btn_change: null,
			no_icon: 'ace-icon fa fa-cloud-upload',
			icon_remove: null,
			roppable: false,
			droppable: true,
			thumbnail: 'small',//false | large | fit
			maxSize: 220000,//bytes
			allowExt: [],//["jpeg", "jpg", "png", "gif"],
			denyExt:[],
			allowMime: [],//["image/jpg", "image/jpeg", "image/png", "image/gif"],
			denyMime:[],
			onchange: null,
			before_change: null,
			before_remove: null,
		},
		// file模板
		fileTpl: '<input type="file" name="{2}" class="{3} {1}" value="{4}" placeholder="{5}" {6} {7} {9} {10} {11} data-original-title="{12} />',
		// file组装
		fileBuild: function(option){},
		// file渲染
		fileRender: function( option ){
			$.extend(me.fileOption,option.fileOption);
			$('.' + option.id).ace_file_input(me.fileOption);
		},
		// editor数据
		editorObj: {},
		// editor参数
		editorOption: {
			cssPath : '',
			allowFileManager : true,
			afterBlur : function(){
				this.sync();
			}
		},
		// editor模板
		editorTpl: '<div class="clearfix">' +
						'<textarea name="{2}" class="{3} {1}" >{4}</textarea>' +
					'</div>',
		// editor组装
		editorBuild: function(option){
		},
		// editor渲染
		editorRender: function( option ){
			$.extend(me.editorOption,option.editorOption);
			me.editorObj[option.id] = KindEditor.create('textarea[name="' + option.id + '"]', me.editorOption);
		},
		// treeview参数
		treeviewOption: {
			'dataSource': function(options, callback){},
			'multiSelect': false,
			'cacheItems' : true,
			'open-icon' : 'fa fa-folder-open',//tree-minus
			'close-icon' : 'ace-icon fa fa-folder',//tree-plus
			'itemSelect' : true,
			'folderSelect': true,
			'selectable': true,
			'selected-icon' : 'ace-icon fa fa-check',
			'unselected-icon' : 'ace-icon fa fa-times',
			'folder-open-icon' : 'ace-icon tree-plus',
			'folder-close-icon' : 'ace-icon tree-minus',
			'loadingHTML' : '<div class="tree-loading"><i class="ace-icon fa fa-refresh fa-spin blue"></i></div>'
		},
		// treeview模板
		treeviewTpl:'<div class="widget-main padding-8 tree-container">' +
						'<ul class="{1}"></ul>' +
					'</div>',
		// treeview组装
		treeviewBuild: function( option ){
			var dataList = option.data;
			var fieldKey = option.fieldKey || 'id';
			var fieldValue = option.fieldValue || 'name';
			if( typeof(option.data) == "string" ) {
				$.ajax({
					type: "get",
					dataType: "json",
					url: me.getUrl(option.data),
					data: option.dataParam || {},
					async: false,
					success: function(data){
						dataList = option.dataSrc != '' ? data.result : data ;
					},
					error: function(data){}
				});
			}
			var dataSource1 = function(options, callback){
				var $data = {};
				if( JSON.stringify(options) == "{}" ) {
					//the root tree
					$data = dataList;
				} else if( JSON.stringify(options.children) != "{}" ) {
					$data = options.children;
				}
				if( typeof($data) == "object" ) {
					var valueArr = option.value ? option.value.toString().split(',') : [];
					$.each($data,function(k,v){
						$data[k]['text'] = v[fieldValue];
						$data[k]['type'] = typeof(v.children) != "undefined" ? 'folder' : 'item';
						//选中判断
						var _value = v[fieldKey], _value = _value.toString();
						if( $.inArray(_value, valueArr) !== -1 ) {
							$data[k]["additionalParameters"] = {'item-selected': true};
						}
					});
				}
				return callback({ data: $data });
				//this setTimeout is only for mimicking some random delay
				/*if($data != null) {
					setTimeout(function(){callback({ data: $data });} , parseInt(Math.random() * 500) + 200);
				}*/
			}
			return dataSource1;
		},
		// treeview渲染
		treeviewRender: function( option ){
			var multiple = option.multiple || false;
			$.extend(me.treeviewOption,option.treeviewOption);
			me.treeviewOption.dataSource = me.treeviewBuild(option);
			me.treeviewOption.multiSelect = option.multiple || false;
			me.treeviewOption.folderSelect = option.folderSelect || true;
			$('.'+option.id).ace_tree(me.treeviewOption);
			$('.'+option.id).tree('discloseVisible');
			$('.tree-container').ace_scroll({size: 250, mouseWheelLock: true});
			$('.'+option.id).on('closed.fu.tree disclosedFolder.fu.tree', function() {
				$('.tree-container').ace_scroll('reset').ace_scroll('start');
			}).on('selected.fu.tree', function(e) {
			}).on('deselected.fu.tree', function(e) {
			});
		},
		// moveselect参数
		moveselectOption: {
			'filterTextClear' : '显示所有',
			'infoTextFiltered': '<span class="label label-purple label-lg">筛选</span>第{0} 到 {1}条数据',
			'infoText': '显示{0}条数据',
		},
		// moveselect模板
		moveselectTpl:'<select name="{2}" class="{3} {1}" data-placeholder="{5}" {9} >' +
					'{4}' +
				'</select>',
		// moveselect渲染
		moveselectRender: function( option ){
			var dualListbox = $('select[name="'+option.field+'"]').bootstrapDualListbox(me.moveselectOption);
			var container = dualListbox.bootstrapDualListbox('getContainer');
			container.find('.btn').addClass('btn-white btn-info btn-bold');
		},
		// color参数
		colorOption: {
			flat: true,
		},
		// color模板
		colorTpl:'<input type="text" class="{3} {1}_color" style="background-color: #{4}; width: 32px;" readonly="readonly">' +
				'<input type="text" name="{2}" class="{3} {1}" value="{4}" placeholder="{5}" {6} {7} {10} {11} data-original-title="{12}">' +
				'<img class="{1}_colorpicker" style="cursor: pointer;cursor: pointer;position:absolute;left:285px;top:10px;" src="resources/assets/images/colorpicker.png">',
		// color组装
		colorBuild: function(option){
		},
		// color渲染
		colorRender: function( option ){
			var htmlId = "." + option.id;
			$( htmlId ).colorpicker(me.colorOption);
			$( htmlId ).on("changeColor", function (e) {
				$( htmlId + "_color" ).css("background",e.color.toHex());
			});
		},
		// 创建表单元素
		// {id:'id',title:'序号',type:"text"},
		// {id:'id',title:'序号',field:'id',type:"text",className:"input-small",value:'',placeholder:"序号",disabled:false,readonly:false},
		// {id:'datePicker',title:'时间',type:"date",format:"yyyy-mm-dd"},
		createElement: function(){
			$.each(me.elementOption,function(k,v){
				if( $.isEmptyObject(v) ) return true;
				var $form = me.element, inputType = '', html = '', render = function(){}, rules = v.rules || {}, messages = v.messages || {};
				var title = v.title || '', type = v.type || 'text', id = v.id || 'id', name = v.field || id, placeholder = v.placeholder || title, tooltip = v.tooltip || '', editType = v.editType || "", titlePrefix = v.titlePrefix || '', titleSuffix = v.titleSuffix || '', group = v.group || '';
				var className = v.className || ( type == 'datetime' || $form.attr('role') != 'form' ? 'input-medium' : 'input-xlarge');
				var _name = name.indexOf('[]') == -1 ? name : name.substr(0,name.length-2);
				v.value = ( me.editData[_name] !== undefined && me.editData[_name] !== '' ) ? me.editData[_name] : ( v.value !== undefined && v.value !== '' ? v.value : '');
				if( typeof(rules) !== 'object' ) {
					rules = JSON.parse(rules);
				}
				if( typeof(messages) !== 'object' ) {
					messages = JSON.parse(messages);
				}
				var value = v.value || '', disabled = v.disabled ? "disabled" : "", readonly = v.readonly ? "readonly" : "", format = v.format || '', multiple = v.multiple ? "multiple" : "", op = v.op || '';
				var required = rules.required != undefined && rules.required ? "required" : "", requiredMark = required ? me.markTpl : "";
				// 修改页情况下
				editDataKey = Object.keys(me.editData);
				if( editDataKey != 0 && editType == 'hidden' ) {
					v.type = type = 'hidden';
					rules = messages = '';
				} else if( editDataKey != 0 && editType == 'disabled' ) {
					disabled = 'disabled';
				} else if( editDataKey != 0 && editType == 'readonly' ) {
					readonly = 'readonly';
				}
				// 表单元素类型
				if( v.type == 'datetime' ) {
					inputType = 'datetime';
					format = format || 'YYYY-MM-DD HH:mm:ss';
				} else if( v.type == 'select' ) {
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请选择...";
					value = me.selectBuild(v);
				} else if( v.type == 'textarea' ) {
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请输入...";
				} else if( v.type == 'file' ) {
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请选择...";
				} else if( v.type == 'editor' ){
					inputType = v.type;
				} else if( v.type == 'treeview' ){
					inputType = v.type;
				} else if( v.type == 'image' ){
					inputType = v.type;
				} else if( v.type == 'color' ){
					inputType = v.type;
					placeholder = v.placeholder = v.placeholder || "请选择...";
				} else if( v.type == 'moveselect' ){
					inputType = v.type;
					value = me.selectBuild(v);
				} else {
					inputType = 'input';
				}
				var inputTypeTpl = me[inputType+'Tpl'];
				if( op == 'between' ) {
					inputTypeTpl += me['separateTpl'] + inputTypeTpl.replace('{2}', '{2}-1');
				}
				if( $.inArray(inputType,['input','datetime']) != -1 && group == '') {
					inputTypeTpl = me['parentTpl'].format(inputTypeTpl);
				}
				if( titleSuffix != '' ){
					titleSuffix = me['titleSuffixTpl'].format(titleSuffix);
				}
				if( titlePrefix != '' ){
					titlePrefix = me['titlePrefixTpl'].format(titlePrefix);
				}
				html = inputTypeTpl.format(type,id,name,className,value,placeholder,disabled,readonly,format,multiple,required,me.tipsTpl,tooltip,titlePrefix,titleSuffix);
				if( v.type != 'hidden' &&  group == '') {
					html = me.elementTpl.format(title,html,requiredMark);
				}
				if(group != '' ){
					$form = $("."+ group).parent();
				}
				$form.append(html);
				render = me[inputType + 'Render'] || render;
				render(v);
				// 设置验证规则
				if( rules != '' ) {
					me.validateRules[v.id] = rules;
				}
				if( messages != '' ) {
					me.validateMessages[v.id] = messages;
				}
			});
		},
		// 创建Element
		load: function(){
			me.beforeLoad();
			me.createElement();
			me.afterLoad();
		},
		// 加载数据前操作
		beforeLoad: function(){},
		// 加载数据之后操作
		afterLoad: function(){
			// 设置样式
			$('[data-rel=tooltip]').tooltip({container:'body'});
			$('[data-rel=popover]').popover({container:'body'});
		},
	});
    /**
     * 扩展 Jquery 对象为 FormElement
     * @param option
     */
    $.fn.formElement = function(option){
        return this.each(function () {
            var $this = $(this),
                data = $this.data('formElement'),
                options = typeof option === 'object' && option;
            if (!data)  {
                $this.data('formElement', (data = new FormElement(this, $.extend({}, options))));
            }
            if (typeof option == 'string') {
                data[option]();
            }
            if(data.autoLoad){
                data.load();
            }
        });
    };
    /**
     * 属性返回对创建此对象的函数的引用
     */
    $.fn.formElement.Constructor = FormElement;

})(jQuery);

